package com.jiehong.mybatisplus;

import java.util.List;

import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.toolkit.StringUtils;

/**
 * 条件装饰类
 * 
 * @author chen
 *
 * @param <T>
 */
public class EntityWrapperDecorate<T> {

	private Wrapper<T> ew;

	public EntityWrapperDecorate() {
		
	}

	public static final String EQ = "=";
	public static final String NE = "!=";
	public static final String GT = ">";
	public static final String GE = ">=";
	public static final String LT = "<";
	public static final String LE = "<=";

	public static final String LIKE = "like";
	public static final String LIKE_OR = "likeOr";
	public static final String NOT_LIKE = "notLike";
	public static final String BETWEEN = "between";
	public static final String NOT_BETWEEN = "notBetween";
	public static final String IS_NULL = "isNull";
	public static final String NOT_NULL = "notNull";
	public static final String IN = "in";
	public static final String NOT_IN = "notIn";
	public static final String ORDER_BY = "orderBy";

	/**
	 * 设置 where 条件 ,
	 * <p>
	 * 支持 orderBy,=,!=,like not like
	 * ,>,>=,<,<=,between,notBetween,isNull,isNotNull,in,notIn
	 * </p>
	 * 
	 * @param ew
	 *            Entity 对象封装操作类，定义T-SQL语法
	 * @param conditionList
	 *            条件封装类
	 * @return
	 */
	public Wrapper<T> setEntityWrapper(Wrapper<T> ew, List<Condition> conditionList) {
		this.ew = ew;
		if (conditionList != null) {

			int aboveLevel = 1;

			for (Condition condition : conditionList) {
				
				// orderBy
				if (ORDER_BY.equals(condition.getCondition())) {
					orderBy(ew, condition);
					continue;
				} else if (LIKE_OR.equals(condition.getCondition())) {// 多个字段模糊查询
					aboveLevel++;// 修改级别
					isOr(aboveLevel, condition);
					LikeOr(condition);
					continue;
				}
				// 判断 or 还是 and
				isOr(aboveLevel, condition);

				switch (condition.getCondition()) {
				case EQ:
				case NE:
				case GT:
				case GE:
				case LT:
				case LE:
					ew.where(condition.getFileName() + " " + condition.getCondition() + " {0}", condition.getParameters());
					break;
				case LIKE:
					ew.like(condition.getFileName(), (String) condition.getParameters());
					break;
				case NOT_LIKE:
					ew.notLike(condition.getFileName(), (String) condition.getParameters());
					break;
				case BETWEEN:
					between(ew, condition, false);
					break;
				case NOT_BETWEEN:
					between(ew, condition, true);
					break;
				case IS_NULL:
					ew.isNull(condition.getFileName());
					break;
				case NOT_NULL:
					ew.isNotNull(condition.getFileName());
					break;
				case IN:
					ew.in(condition.getFileName(), (String) condition.getParameters());
					break;
				case NOT_IN:
					ew.notIn(condition.getFileName(), (String) condition.getParameters());
					break;

				default:
					throw new IllegalArgumentException("条件参数错误：" + condition.getCondition());
				}

				aboveLevel = condition.getLevel();

			}
		}

		return ew;
	}

	/**
	 * 多个字段模糊查询
	 * 
	 * @param condition
	 */
	private void LikeOr(Condition condition) {
		List<String> fileNameArray = StringUtils.splitWorker((String) condition.getFileName(), ",", -1, false);
		for (int i = 0; i < fileNameArray.size(); i++) {
			ew.like(fileNameArray.get(i), (String) condition.getParameters());
			if (i < fileNameArray.size() - 1) {
				ew.or();
			}

		}
	}

	/**
	 * 判断 or 还是 and
	 * 
	 * @param aboveLevel
	 * @param condition
	 */
	private void isOr(int aboveLevel, Condition condition) {
		// 判断 or 还是 and
		if (condition.isOr()) {
			if (condition.getLevel() != aboveLevel) {
				ew.orNew();
			} else {
				ew.or();
			}
		} else {
			if (condition.getLevel() != aboveLevel) {
				ew.andNew();
			} else {
				ew.and();
			}
		}
	}

	/**
	 * 
	 * orderBy 方法封装
	 * 
	 * @param ew
	 * @param condition
	 */
	private void orderBy(Wrapper<?> ew, Condition condition) {
		// 判断升序还是降序
		boolean isAsc = false;
		if ("asc".equalsIgnoreCase((String) condition.getParameters())) {
			isAsc = true;
		} else if ("desc".equalsIgnoreCase((String) condition.getParameters())) {
			isAsc = false;
		} else {
			throw new IllegalArgumentException("orderBy 参数错误：" + condition.getParameters());
		}
		ew.orderBy(condition.getFileName(), isAsc);
	}

	/**
	 * between 方法封装
	 * 
	 * @param ew
	 * @param condition
	 * @param isNot
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private Wrapper<?> between(Wrapper<?> ew, Condition condition, boolean isNot) {
		List<Object> parametersList = null;
		if (condition.getParameters() instanceof List) {
			parametersList = (List<Object>) condition.getParameters();
		} else {
			throw new IllegalArgumentException("between 参数错误！");
		}
		if (isNot) {
			ew.notBetween(condition.getFileName(), parametersList.get(0), parametersList.get(1));
		} else {
			ew.between(condition.getFileName(), parametersList.get(0), parametersList.get(1));
		}
		return ew;
	}

	

	public Wrapper<T> getEw() {
		return ew;
	}

	public void setEw(Wrapper<T> ew) {
		this.ew = ew;
	}

}
